package com.example.page.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.page.entity.vo.ClazzVo;
import com.example.page.entity.Student;
import com.example.page.service.ClazzService;
import com.example.page.service.StudentService;
import lombok.RequiredArgsConstructor;
import lombok.val;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

/**
 * <p>
 * 测试
 * </p>
 *
 * @author chen
 * @since 2025-02-05
 */
@RestController
@RequiredArgsConstructor
public class TestController {

    private final ClazzService clazzService;
    private final StudentService studentService;


    /*
       问题复现
     */
    @GetMapping("/{size}/{current}")
    public IPage<ClazzVo> problem(@PathVariable("size") int size, @PathVariable("current") int current) {
        return clazzService.getClazzPageWithProblem(new Page<>(current, size));
    }

    /*
        解决方式一：先对主表进行分页，然后遍历结果集，再查询子表（多次查询，多次连接）
     */
    @GetMapping("/t1/{size}/{current}")
    public Page<ClazzVo> test1(@PathVariable("size") int size, @PathVariable("current") int current) {
        val clazzPage = clazzService.page(new Page<>(current, size));

        val clazzVos = clazzPage.getRecords()
                .stream()
                .map(clazz -> {
                    val cid = clazz.getId();
                    val students = studentService.lambdaQuery()
                            .eq(Student::getCid, cid)
                            .list();

                    val clazzVo = new ClazzVo();
                    clazzVo.setId(clazz.getId());
                    clazzVo.setName(clazz.getName());
                    clazzVo.setStudents(students);
                    return clazzVo;
                })
                .toList();

        val classVoPage = new Page<ClazzVo>();

        classVoPage.setCurrent(clazzPage.getCurrent());
        classVoPage.setSize(clazzPage.getSize());
        classVoPage.setTotal(clazzPage.getTotal());
        classVoPage.setRecords(clazzVos);

        return classVoPage;
    }


    /*
        解决方式二：在 Mybatis xml 文件中的 collection 中嵌套查询（多次查询，一次连接）
     */
    @GetMapping("/t2/{size}/{current}")
    public IPage<ClazzVo> test2(@PathVariable("size") int size, @PathVariable("current") int current){
        return clazzService.getClazzPageWithSolution1(new Page<>(current, size));
    }

    /*
        解决方案三：自定义 mysql 分页方言，使用 JsqlParser 将 limit 下推到主表（一次连接，一次查询）
     */
    @GetMapping("/t3/{size}/{current}")
    public IPage<ClazzVo> test3(@PathVariable("size") int size, @PathVariable("current") int current){
        return clazzService.getClazzPageWithSolution2(new Page<>(current, size));
    }
}
